package cn.yunyichina.provider.base.service.impl;

import java.util.Calendar;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.fy.util.CommonUtil;
import com.fy.util.Record;
import com.fy.util.RecordSet;
import com.fy.util.db.CommonService;

import cn.yunyichina.provider.base.dao.sync.impl.ImportSourceDao;
import cn.yunyichina.provider.iface.entity.ErrorCodeDefine;
import cn.yunyichina.utils.commons.StringUtils;
import cn.yunyichina.utils.convert.JsonUtils;

/**
 * 订单表pu_personal_user旧数据库同步到新数据库
 * @author adriftor
 *
 */
@Service("usersyncServiceImpl")
public class UserSyncServiceImpl extends CommonService {
	
	private static final Logger logger = LoggerFactory.getLogger(UserSyncServiceImpl.class);
	
	/**
	 * 数据来源表
	 */
	private static final String sourceTableName = "v_pu_personal_user_sync";

	
	/**
	 * 数据目标表
	 */
	private static final String targetTableName = "pu_personal_user";
	
	/**
	 * 标志字段
	 */
	private static final String markFieldName = "user_sync_info";
	/**
	 * 数据同步时，分页大小
	 */
	private static final int pageSize = 300;
	
	public void doUserSync() {

		Long start = System.currentTimeMillis();
		ImportSourceDao dao = null;
		try {
			logger.debug(sourceTableName + "数据同步开始");

			dao = new ImportSourceDao();
			dao.begin();

			String sql;

			// 获取上次同步截止的最大ID
			sql = "select max(sync_max_id) from sys_sync_id where sync_table='" + targetTableName + "'";
			String maxId = this.queryForString(sql);
			if (StringUtils.isEmpty(maxId)) {
				this.update("delete from sys_sync_id where sync_table='" + targetTableName + "'");
				this.update("insert sys_sync_id(sync_table,sync_max_id) value ('" + targetTableName + "','')");
				maxId = "";
			}
			Calendar c = Calendar.getInstance();
			c.add(Calendar.DATE, -1);
			String curTime = CommonUtil.dateToStr(c.getTime());

			boolean flagDaoCommit = false;
			// 删除已经成功同步的记录
			if ( ! StringUtils.isBlank(maxId)) {
				sql = "delete from pu_medical_card_sync where sync_id<'" + maxId + "'  and insert_time<'"
						+ curTime
						+ "' and user_sync_info='' and family_sync_info='' and openid_sync_info='' and card_sync_info='' and relation_sync_info=''";
				dao.update(sql);
				flagDaoCommit = true;
			}

			// 总记录数
			int recordCount = 0;
			// 出错次数
			int errorCount = 0;

			// 处理
			sql = "select count(*) as cnt from " + sourceTableName + " where sync_id>'" + maxId + "'";
			int count = dao.queryForInt(sql);

			for (int m = 0; m < count; m += pageSize) {
				sql = "select * from " + sourceTableName + " where sync_id>'" + maxId + "' order by sync_id";
				RecordSet rs = dao.query(sql, new Record(), 1, pageSize);
				if (rs.size() > 0) {

					// 重新确定最大ID
					maxId = rs.getRecord(rs.size() - 1).getString("sync_id");
					recordCount += rs.size();

					for (int i = 0; i < rs.size(); i++) {
						Record rd = rs.getRecord(i);
						try {
							if (rd.gIntValue("add_flag") == 1) {// 新增

								this.insertData(targetTableName, rd);

							} else if (rd.gIntValue("update_flag") == 1) {// 更新

								this.updateData(targetTableName, rd, "id");
							} else {
								logger.error(sourceTableName + "无效的同步数据：" + JsonUtils.toJsonString(rd));
							}

						} catch (Exception e) {
							errorCount++;
							logger.error(sourceTableName + "同步订单数据错误，数据为：" + JsonUtils.toJsonString(rd));
							logger.error(ErrorCodeDefine.getStackTrace(e));

							// 记录错误信息
							try {
								String errorInfo = e.toString();
								if (errorInfo.length() > 100) {
									errorInfo = errorInfo.substring(0, 100);
								}
								rd.put(markFieldName, errorInfo);
								dao.update("update pu_medical_card_sync set " + markFieldName
										+ "=? where sync_id=? and length(" + markFieldName + ")=0 ", rd);
							} catch (Exception e2) {

								logger.error(sourceTableName + "同步错误，无法更新源数据标志位，数据为：" + JsonUtils.toJsonString(rd));
								logger.error(ErrorCodeDefine.getStackTrace(e2));
							}
						}

					}

					// 标记最大ID值
					this.update("update sys_sync_id set sync_max_id='" + maxId + "' where sync_table='"
							+ targetTableName + "'");
					this.commit();

					// 错误数据太多，退出同步
					if (errorCount == recordCount) {
						logger.error(sourceTableName + "同步全部出错，本次同步结束");
						break;
					}

				}
			}

			if (errorCount > 0 || flagDaoCommit) {
				dao.commit();
			}

			if (recordCount > 0) {
				if (errorCount == 0) {
					logger.info(sourceTableName + "数据同步成功，耗时：" + (System.currentTimeMillis() - start) + "毫秒,处理记录总数"
							+ recordCount);
				} else {
					logger.error(sourceTableName + "数据同步完成，但存在异常数据，耗时：" + (System.currentTimeMillis() - start)
							+ "毫秒,处理记录总数" + recordCount + ",其中错误记录数：" + errorCount);
				}
			} else {
				logger.info(sourceTableName + "没有需要同步的记录");
			}

		} catch (Exception ex) {
			logger.error(sourceTableName + "数据同步异常,耗时：" + (System.currentTimeMillis() - start) + "毫秒\n"
					+ ErrorCodeDefine.getStackTrace(ex));

		} finally {
			try {
				if (dao != null) {
					dao.releaseCon();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}
	

}
